package com.yeeverse.sdk.util;


import com.alibaba.fastjson.JSONObject;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class AES128CBC {

    // constants
    private static final String DEFAULT_CHARSET = "utf-8";
    private static final String ALGORITHM_NAME = "AES";
    private static final String ALGORITHM_STR = ALGORITHM_NAME + "/CBC/PKCS5Padding";
    private static final String IV = "yeeverse-cbc-key";

    /**
     * get cipher
     *
     * @param mode
     * @param key
     * @param charset
     * @return
     * @throws Exception
     */
    private static Cipher getCipher(int mode, String key, String charset) throws Exception {
        // secretKeySpec
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(charset), ALGORITHM_NAME);
        // ivParameterSpec
        IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes(charset));
        // cipher
        Cipher cipher = Cipher.getInstance(ALGORITHM_STR);
        cipher.init(mode, secretKeySpec, ivParameterSpec);
        return cipher;
    }

    public static String encrypt(String a, String key, String charset) throws Exception {
        Cipher cipher = getCipher(Cipher.ENCRYPT_MODE, key, charset);
        byte[] resultByte = cipher.doFinal(a.getBytes(charset));
        return base64BytesToString(resultByte, charset);
    }

    public static String encrypt(String a, String key) throws Exception {
        return encrypt(a, key, DEFAULT_CHARSET);
    }

    public static String decrypt(String a, String key, String charset) throws Exception {
        Cipher cipher = getCipher(Cipher.DECRYPT_MODE, key, charset);
        byte[] inputByte = base64stringToBytes(a, charset);
        byte[] resultByte = cipher.doFinal(inputByte);
        return new String(resultByte, charset);
    }

    public static String decrypt(String a, String key) throws Exception {
        return decrypt(a, key, DEFAULT_CHARSET);
    }

    private static String base64BytesToString(byte[] bytes, String charset) throws Exception {
        return new String(Base64.getEncoder().encode(bytes), charset);
    }

    private static byte[] base64stringToBytes(String string, String charset) throws Exception {
        return Base64.getDecoder().decode(string.getBytes(charset));
    }

    /**
     * 解析参数并转成json返回
     *
     * @param paramsStr 加密参数
     * @param paramsKey 签名key
     * @return 返回json对象结果
     */
    public static JSONObject decryptToJsonObject(String paramsStr, String paramsKey) throws Exception {
        String params = decrypt(paramsStr, paramsKey);
        if (!StringUtils.isBlank(params)) {
            return JSONObject.parseObject(params);
        }
        return null;
    }

    /**
     * 随机生成秘钥
     */
    public static String getKey() {
        String s = null;
        try {
            KeyGenerator kg = KeyGenerator.getInstance("AES");
            kg.init(128);
            //要生成多少位，只需要修改这里即可128, 192或256
            SecretKey sk = kg.generateKey();
            byte[] b = sk.getEncoded();
            s = byteToHexString(b);
        } catch (NoSuchAlgorithmException e) {
            System.out.println("没有此算法");

        }
        return s;
    }

    /**
     * byte数组转化为16进制字符串
     *
     * @param bytes
     * @return
     */
    public static String byteToHexString(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            String strHex = Integer.toHexString(bytes[i]);
            if (strHex.length() > 3) {
                sb.append(strHex.substring(6));
            } else {
                if (strHex.length() < 2) {
                    sb.append("0" + strHex);
                } else {
                    sb.append(strHex);
                }
            }
        }
        return sb.toString();
    }


    public static void main(String[] args) throws Exception {
        String key = getKey();
        System.out.println(key);
        System.out.println(decrypt("ilOg79TO9BfOlrBDBtVkhi2FwiMy7iBII60A5zcouro=", "14f9ccddedefdc7e73605bf15c3a6f3b"));
    }

}
